package com.powernode.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.domain.Prod;
import com.powernode.domain.ProdTagReference;
import com.powernode.domain.Sku;
import com.powernode.mapper.ProdMapper;
import com.powernode.mapper.ProdTagReferenceMapper;
import com.powernode.mapper.SkuMapper;
import com.powernode.service.ProdService;
import com.powernode.service.ProdTagReferenceService;
import com.powernode.service.SkuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ProdServiceImpl extends ServiceImpl<ProdMapper, Prod> implements ProdService {

    @Autowired
    ProdMapper prodMapper;
    @Autowired
    ProdTagReferenceService prodTagReferenceService;
    @Autowired
    SkuService skuService;
    @Autowired
    ProdTagReferenceMapper prodTagReferenceMapper;
    @Autowired
    SkuMapper skuMapper;

    /**
     * 保存商品信息
     *
     * @param prod 商品对象，包含商品的基本信息和关联信息，如标签、SKU等
     * @return 商品是否成功保存返回true表示成功，否则表示失败
     */
    @Override
    public Boolean saveProd(Prod prod) {
        // 新增商品
        prod.setShopId(1L);
        prod.setSoldNum(0);
        prod.setCreateTime(new Date());
        prod.setUpdateTime(new Date());
        prod.setPutawayTime(new Date());
        prod.setVersion(0);

        // 将商品的配送模式对象转换为JSON字符串保存
        Prod.DeliveryModeVo deliveryModeVo = prod.getDeliveryModeVo();
        prod.setDeliveryMode(JSONObject.toJSONString(deliveryModeVo));

        // 插入商品信息到数据库
        int i = prodMapper.insert(prod);
        if (i > 0) {
            // 获取插入成功商品的ID
            Long prodId = prod.getProdId();

            // 处理商品标签，如果存在则批量插入商品标签关联表
            List<Long> tagList = prod.getTagList();
            if (CollectionUtil.isNotEmpty(tagList) && tagList.size() != 0) {
                List<ProdTagReference> prodTagReferenceList = new ArrayList<>();
                tagList.forEach(tagId -> {
                    ProdTagReference prodTagReference = new ProdTagReference();
                    prodTagReference.setProdId(prodId);
                    prodTagReference.setTagId(tagId);
                    prodTagReference.setCreateTime(new Date());
                    prodTagReference.setShopId(1L);
                    prodTagReference.setStatus(1);
                    prodTagReferenceList.add(prodTagReference);
                });
                prodTagReferenceService.saveBatch(prodTagReferenceList);
            }

            // 处理商品SKU，如果存在则批量插入SKU信息
            List<Sku> skuList = prod.getSkuList();
            if (CollectionUtil.isNotEmpty(skuList) && skuList.size() != 0) {
                skuList.forEach(sku -> {
                    sku.setProdId(prodId);
                    sku.setCreateTime(new Date());
                    sku.setUpdateTime(new Date());
                    sku.setVersion(0);
                    sku.setActualStocks(sku.getStocks());
                });
                skuService.saveBatch(skuList);
            }
        }
        // 返回商品插入结果
        return i > 0;
    }

    /**
     * 根据产品ID查询产品信息
     * <p>
     * 此方法通过产品ID从数据库中检索产品信息，包括产品详情、产品标签和产品SKU信息
     * 它首先从prodMapper中获取产品基本信息，然后分别从prodTagReferenceMapper和skuMapper中获取产品的标签和SKU信息
     * 如果产品有关联的标签，将标签ID列表设置到产品对象中同时，将所有SKU信息设置到产品对象中
     *
     * @param prodId 产品ID，用于查询特定产品的详细信息
     * @return 返回一个包含详细信息（包括标签和SKU）的产品对象
     */
    @Override
    public Prod queryProdInfoById(Long prodId) {
        // 从数据库中根据产品ID查询产品基本信息
        Prod prod = prodMapper.selectById(prodId);
        // 查询与产品关联的所有标签引用
        List<ProdTagReference> prodTagReferenceList = prodTagReferenceMapper.selectList(new LambdaQueryWrapper<ProdTagReference>().eq(ProdTagReference::getProdId, prodId));
        // 如果产品有关联的标签，提取标签ID列表
        if (CollectionUtil.isNotEmpty(prodTagReferenceList) && prodTagReferenceList.size() != 0) {
            List<Long> tagIdList = prodTagReferenceList.stream().map(ProdTagReference::getTagId).collect(Collectors.toList());
            // 将标签ID列表设置到产品对象中
            prod.setTagList(tagIdList);
        }
        // 查询与产品关联的所有SKU信息
        List<Sku> skus = skuMapper.selectList(new LambdaQueryWrapper<Sku>().eq(Sku::getProdId, prodId));
        // 将SKU信息设置到产品对象中
        prod.setSkuList(skus);
        // 返回包含详细信息的产品对象
        return prod;
    }

    /**
     * 修改商品信息
     * <p>
     * 该方法主要用于更新商品的基本信息、标签信息和库存信息
     * 它首先删除现有的商品标签关联，然后根据新的商品信息重新插入标签关联
     * 同时，它更新商品的库存信息，并最终更新商品的基本信息
     *
     * @param prod 商品对象，包含要更新的商品信息
     * @return 返回一个布尔值，表示商品信息是否成功更新
     */
    @Override
    public Boolean modifyProdInfo(Prod prod) {
        // 获取商品ID
        Long prodId = prod.getProdId();
        // 删除商品与标签的原有关联
        prodTagReferenceMapper.delete(new LambdaQueryWrapper<ProdTagReference>().eq(ProdTagReference::getProdId, prodId));
        // 处理商品标签，如果存在则批量插入商品标签关联表
        List<Long> tagList = prod.getTagList();
        if (CollectionUtil.isNotEmpty(tagList) && tagList.size() != 0) {
            List<ProdTagReference> prodTagReferenceList = new ArrayList<>();
            tagList.forEach(tagId -> {
                ProdTagReference prodTagReference = new ProdTagReference();
                prodTagReference.setProdId(prodId);
                prodTagReference.setTagId(tagId);
                prodTagReference.setCreateTime(new Date());
                prodTagReference.setShopId(1L);
                prodTagReference.setStatus(1);
                prodTagReferenceList.add(prodTagReference);
            });
            // 批量保存商品标签关联
            prodTagReferenceService.saveBatch(prodTagReferenceList);
        }
        // 更新商品的库存信息
        List<Sku> skuList = prod.getSkuList();
        skuList.forEach(sku -> {
            sku.setUpdateTime(new Date());
            sku.setActualStocks(sku.getStocks());
        });
        // 批量更新库存信息
        skuService.updateBatchById(skuList);
        // 更新商品的最后修改时间
        prod.setUpdateTime(new Date());
        // 更新商品基本信息，并返回更新结果
        return prodMapper.updateById(prod) > 0;
    }

    /**
     * 根据产品ID删除产品及其关联信息
     * 此方法首先删除产品标签关联信息，然后删除与产品关联的库存信息，
     * 最后删除产品本身它体现了在删除产品时，也需要处理与之关联的数据，
     * 以维护数据库数据的一致性
     *
     * @param prodId 产品ID，用于标识要删除的产品
     * @return 返回一个布尔值，表示产品是否删除成功
     */
    @Override
    public Boolean removeProdById(Long prodId) {
        // 删除产品标签关联信息
        prodTagReferenceMapper.delete(new LambdaQueryWrapper<ProdTagReference>().eq(ProdTagReference::getProdId, prodId));
        // 删除与产品关联的库存信息
        skuMapper.delete(new LambdaQueryWrapper<Sku>().eq(Sku::getProdId, prodId));
        // 删除产品本身，并判断删除是否成功
        return prodMapper.deleteById(prodId) > 0;
    }

    /**
     * 根据商品ID查询微信商品信息
     *
     * @param prodId 商品ID
     * @return 返回包含SKU列表的商品信息
     */
  // 重写查询微信商品信息的方法，根据商品ID获取商品详情
    @Override
    public Prod queryWxProdInfoByProdId(Long prodId) {
        // 使用prodMapper通过商品ID查询商品基本信息
        Prod prod = prodMapper.selectById(prodId);

        // 使用skuMapper查询与该商品ID关联的所有SKU信息列表
        // LambdaQueryWrapper用于构建查询条件，这里指定查询条件为SKU的prodId字段等于传入的prodId
        List<Sku> skus = skuMapper.selectList(new LambdaQueryWrapper<Sku>().eq(Sku::getProdId, prodId));

        // 将查询到的SKU列表设置到商品对象中
        prod.setSkuList(skus);

        // 返回包含SKU列表的商品对象
        return prod;
    }

}
